/*-------------------------------------------------------------------------
 *
 * pg_aggregate.h
 *	  “聚合”系统目录（pg_aggregate）的定义。
 *
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/catalog/pg_aggregate.h
 *
 * NOTES
 *	  Catalog.pm 模块读取此文件并推导出模式信息。
 *
 *-------------------------------------------------------------------------
 */
#ifndef PG_AGGREGATE_H
#define PG_AGGREGATE_H

#include "catalog/genbki.h"
#include "catalog/pg_aggregate_d.h"

#include "catalog/objectaddress.h"
#include "nodes/pg_list.h"

/* ----------------------------------------------------------------
 *		pg_aggregate定义。
 *		cpp将其转换为typedef struct FormData_pg_aggregate
 * ----------------------------------------------------------------
 */
CATALOG(pg_aggregate,2600,AggregateRelationId)
{
	/* pg_proc聚合本身的OID */
	regproc		aggfnoid BKI_LOOKUP(pg_proc);

	/* 聚合类型，请参见下面的AGGKIND_类别 */
	char		aggkind BKI_DEFAULT(n);

	/* “直接”参数的数量 */
	int16		aggnumdirectargs BKI_DEFAULT(0);

	/* 过渡函数 */
	regproc		aggtransfn BKI_LOOKUP(pg_proc);

	/* 最终函数（如果没有则为 0） */
	regproc		aggfinalfn BKI_DEFAULT(-) BKI_LOOKUP_OPT(pg_proc);

	/* 组合函数（如果没有为 0） */
	regproc		aggcombinefn BKI_DEFAULT(-) BKI_LOOKUP_OPT(pg_proc);

	/* 将 transtype 转换为 bytea 的函数（如果没有为 0） */
	regproc		aggserialfn BKI_DEFAULT(-) BKI_LOOKUP_OPT(pg_proc);

	/* 将 bytea 转换为 transtype 的函数（如果没有为 0） */
	regproc		aggdeserialfn BKI_DEFAULT(-) BKI_LOOKUP_OPT(pg_proc);

	/* 移动聚合模式的前向函数（如果没有为 0） */
	regproc		aggmtransfn BKI_DEFAULT(-) BKI_LOOKUP_OPT(pg_proc);

	/* 移动聚合模式的逆向函数（如果没有为 0） */
	regproc		aggminvtransfn BKI_DEFAULT(-) BKI_LOOKUP_OPT(pg_proc);

	/* 移动聚合模式的最终函数（如果没有则为0） */
	regproc		aggmfinalfn BKI_DEFAULT(-) BKI_LOOKUP_OPT(pg_proc);

	/* 为aggfinalfn传递额外的虚拟参数为true */
	bool		aggfinalextra BKI_DEFAULT(f);

	/* 为aggmfinalfn传递额外的虚拟参数为true */
	bool		aggmfinalextra BKI_DEFAULT(f);

	/* 告诉aggfinalfn是否修改过渡状态 */
	char		aggfinalmodify BKI_DEFAULT(r);

	/* 告诉aggmfinalfn是否修改过渡状态 */
	char		aggmfinalmodify BKI_DEFAULT(r);

	/* 相关的排序操作符（如果没有则为0） */
	Oid			aggsortop BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_operator);

	/* 聚合的过渡（状态）数据的类型 */
	Oid			aggtranstype BKI_LOOKUP(pg_type);

	/* 状态数据的估计大小（默认估计为0） */
	int32		aggtransspace BKI_DEFAULT(0);

	/* 移动聚合状态数据的类型（如果没有则为0） */
	Oid			aggmtranstype BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_type);

	/* 移动聚合状态的估计大小（默认估计为0） */
	int32		aggmtransspace BKI_DEFAULT(0);

#ifdef CATALOG_VARLEN			/* 可变长度字段从这里开始 */

	/* 过渡状态的初始值（可以为NULL） */
	text		agginitval BKI_DEFAULT(_null_);

	/* 移动聚合状态的初始值（可以为 NULL） */
	text		aggminitval BKI_DEFAULT(_null_);
#endif
} FormData_pg_aggregate;

/* ----------------
 *		Form_pg_aggregate 对应于一个指向拥有
 *		pg_aggregate 关系格式的元组的指针。
 * ----------------
 */
typedef FormData_pg_aggregate *Form_pg_aggregate;

DECLARE_TOAST(pg_aggregate, 4159, 4160);

DECLARE_UNIQUE_INDEX_PKEY(pg_aggregate_fnoid_index, 2650, AggregateFnoidIndexId, on pg_aggregate using btree(aggfnoid oid_ops));

#ifdef EXPOSE_TO_CLIENT_CODE

/*
 * 聚合类型列的符号值。我们区分普通聚合
 * 与有序集聚合（具有两组参数，即
 * 直接参数和聚合参数）以及假设集聚合
 * （这是有序集聚合的一个子类，其中最后
 * 直接参数的数量和数据类型必须与
 * 聚合参数匹配）。
 */
#define AGGKIND_NORMAL			'n'
#define AGGKIND_ORDERED_SET		'o'
#define AGGKIND_HYPOTHETICAL	'h'

/* 使用此宏来测试“包括假设情况的有序集聚合” */
#define AGGKIND_IS_ORDERED_SET(kind)  ((kind) != AGGKIND_NORMAL)

/*
 * aggfinalmodify 和 aggmfinalmodify 列的符号值。
 * 最好，finalfns 不会修改过渡状态值，
 * 但在某些情况下这会导致过多的性能损失。我们区分
 * “纯只读”和“任意破坏”的情况，以及
 * 允许多个 finalfn 调用的中间情况，但在第一次 finalfn 调用后
 * transfn 将无法再次应用。
 */
#define AGGMODIFY_READ_ONLY			'r'
#define AGGMODIFY_SHAREABLE			's'
#define AGGMODIFY_READ_WRITE		'w'

#endif							/* EXPOSE_TO_CLIENT_CODE */


extern ObjectAddress AggregateCreate(const char *aggName,
									 Oid aggNamespace,
									 bool replace,
									 char aggKind,
									 int numArgs,
									 int numDirectArgs,
									 oidvector *parameterTypes,
									 Datum allParameterTypes,
									 Datum parameterModes,
									 Datum parameterNames,
									 List *parameterDefaults,
									 Oid variadicArgType,
									 List *aggtransfnName,
									 List *aggfinalfnName,
									 List *aggcombinefnName,
									 List *aggserialfnName,
									 List *aggdeserialfnName,
									 List *aggmtransfnName,
									 List *aggminvtransfnName,
									 List *aggmfinalfnName,
									 bool finalfnExtraArgs,
									 bool mfinalfnExtraArgs,
									 char finalfnModify,
									 char mfinalfnModify,
									 List *aggsortopName,
									 Oid aggTransType,
									 int32 aggTransSpace,
									 Oid aggmTransType,
									 int32 aggmTransSpace,
									 const char *agginitval,
									 const char *aggminitval,
									 char proparallel);

#endif							/* PG_AGGREGATE_H */
